package com.kool.kmqtt.server.parser;

import com.kool.kmqtt.server.packet.FixedHeader;
import com.kool.kmqtt.server.packet.Packet;
import io.netty.buffer.ByteBuf;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public abstract class PacketParser {
    protected Packet packet;

    public PacketParser(FixedHeader fixedHeader) {
        packet = new Packet();
        packet.setFixedHeader(fixedHeader);
    }

    /**
     * 解析固定报头
     *
     * @param in
     * @return
     */
    public static FixedHeader parseFixedHeader(ByteBuf in) {
        FixedHeader fixedHeader = new FixedHeader();
        byte packageTypeFlags = in.readByte();
        int packageType = Byte.toUnsignedInt(packageTypeFlags) >> 4;
        fixedHeader.setPacketType(packageType);

        int flags = packageTypeFlags & 0x0f;
        fixedHeader.setFlags(flags);
        int remainingLength = 0;
        byte remainingLength0 = in.readByte();
        remainingLength += remainingLength0 & 0x7f;
        if (0x80 == (remainingLength0 & 0x80)) {
            byte remainingLength1 = in.readByte();
            remainingLength += remainingLength1 & 0x7f << 7;
            if (0x80 == (remainingLength1 & 0x80)) {
                byte remainingLength2 = in.readByte();
                remainingLength += remainingLength2 & 0x7f << 14;
                if (0x80 == (remainingLength2 & 0x80)) {
                    byte remainingLength3 = in.readByte();
                    remainingLength += remainingLength3 & 0x7f << 21;
                }
            }
        }
        fixedHeader.setRemainingLength(remainingLength);

        return fixedHeader;
    }

    /**
     * 解析报文的可变报头和载荷
     *
     * @param in
     * @return
     */
    public Packet parse(ByteBuf in) {
        parseVariableHeader(in);
        parsePayload(in);
        return packet;
    }

    public abstract void parseVariableHeader(ByteBuf in);

    public abstract void parsePayload(ByteBuf in);
}
